/**
 * CopyRight © 2012 USTC SINOVATE SOFTWARE CO.LTD All Rights Reserved.
 */

package com.cmcc.zysoft.infocollection.thread;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cmcc.zysoft.framework.utils.StringUtil;
import com.cmcc.zysoft.infocollection.constant.URLConstant;
import com.cmcc.zysoft.infocollection.model.Resource;
import com.cmcc.zysoft.infocollection.service.ResourcePcService;

/**
 * @author 袁凤建
 * <br />邮箱: yuan.fengjian@ustcinfo.com
 * <br />描述: QueryJobThread.java 商户信息采集任务处理线程.
 * <br />版本: 1.0.0
 * <br />日期: 2013-8-26 上午9:28:23
 * <br />CopyRight © 2012 USTC SINOVATE SOFTWARE CO.LTD All Rights Reserved.
 */

public class QueryJobThread extends ApplicationObjectSupport implements Runnable {
	
	/**
	 * 日志.
	 */
	private static Logger logger = LoggerFactory.getLogger(QueryJobThread.class);
	
	/**
	 * 信息查询接口URL前缀.
	 */
	private String infoQueryUrlPrefix;
	
	/**
	 * 属性名称: resourcePcService.
	 * 类       型: ResourcePcService.
	 */
	private ResourcePcService resourcePcService;
	
	/**
	 * 构造方法.
	 */
	public QueryJobThread() {
		
	}
	
	/**
	 * 构造方法.
	 * @param resourcePcService resourcePcService
	 * @param infoQueryUrlPrefix 信息查询接口URL前缀
	 */
	public QueryJobThread(ResourcePcService resourcePcService, String infoQueryUrlPrefix) {
		this.resourcePcService = resourcePcService;
		this.infoQueryUrlPrefix = infoQueryUrlPrefix;
	}

	/**
	 * 线程运行方法.
	 */
	@Override
	public void run() {
		String infoId = "";
		String response = "";
		String dataSource = URLConstant.DATA_SOURCE;
		//获取所有入库状态为入库等待(state=1)或入库中(state=2)的资源信息
		List<Resource> resourceList = this.resourcePcService.getResourceList();
		System.out.println("================================================================================");
		System.out.println("总数  : " +  resourceList.size());
		System.out.println("入库状态url : " + infoQueryUrlPrefix);
		System.out.println("================================================================================");
		if(null != resourceList && !resourceList.isEmpty()) {
			Resource resource = null;
			for(int i = 0; i < resourceList.size(); i++) {
				resource = resourceList.get(i);
				System.out.println("resourceId : " + resource.getResourceId());
				infoId = resource.getInfoId();
				response = this.getQueryResult(infoId, dataSource);
				this.queryJob(resource, response);
				System.out.println("response   : " + response);
			}
		}
		System.out.println("================================================================================");
	}
	
	/**
	 * 商户信息采集任务-解析查询结果,并将数据持久化至数据库.
	 * @param resource 商户信息
	 * @param response 查询返回信息
	 */
	@Transactional
	public void queryJob(Resource resource, String response) {
		logger.debug("#########  商户信息采集任务开始!  #########");
		String shopId = ""; //商户ID
		String state = ""; //入库状态(1-入库等待,2-入库中,3-入库完成,4-入库失败)
		if(StringUtils.hasText(response)) {
			JSONObject object = JSONObject.parseObject(response);
			if("1".equals(object.get("status").toString())) {
				JSONArray object2 = object.getJSONArray("result");
				//判断中央库中商户是否删除
				if("{}".equals(object2.getJSONObject(0).toString())) { //中央库中商户已删除,更新本地入库状态为:入库失败(state=4)
					resource.setState("4");
					this.resourcePcService.updateEntity(resource);
				} else { //中央库商户未删除,更新中央库的入库状态至本地库
					for(int i = 0; i < object2.size(); i++) {
						JSONObject config = object2.getJSONObject(i);
						shopId = config.getString("id");
			        	state = config.getString("state");
					}
					//若入库状态发生变化,将新的入库状态持久化至数据库;否则不做任何操作
					if(!state.equals(resource.getState())) {
						resource.setState(state);
						resource.setShopId(shopId);
						this.resourcePcService.updateEntity(resource);
					}
				}
				System.out.println("================================================================================");
	        	System.out.println("resourceId     : " + resource.getResourceId());
	        	System.out.println("流水号infoId   : " + resource.getInfoId());
	        	System.out.println("入库状态state  : " + resource.getState());
	        	System.out.println("================================================================================");
			}
		}
		logger.debug("#########  商户信息采集任务结束!  #########");
	}
	
	/**
	 * 根据流水号和数据来源查询中央库的商户入库信息.
	 * @param infoId 流水号
	 * @param dataSource 数据来源
	 * @return String
	 */
	private String getQueryResult(String infoId, String dataSource) {
		String response = "";
		try {
			String url = infoQueryUrlPrefix;
			System.out.println("================================================================================");
			System.out.println("入库状态url : " + infoQueryUrlPrefix);
			System.out.println("================================================================================");
			String parameters = StringUtil.formatMsg(URLConstant.INFO_QUERY_URL_PARAMETER, infoId, dataSource);
			//处理参数中的空格(" "),解决505错误问题(使用%20替换空格)
			parameters = parameters.replaceAll(" ", "%20");
			URL postUrl = new URL(url);
			HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setInstanceFollowRedirects(false);
			connection.setRequestMethod("POST");
			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			connection.setRequestProperty("charset", "UTF-8");
			connection.setRequestProperty("Content-Length", "" + Integer.toString(parameters.getBytes().length));
			connection.setUseCaches(false);
			DataOutputStream out = new DataOutputStream(connection.getOutputStream());
			out.writeBytes(parameters);
			out.flush();
			out.close();
			BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
	        String line = "";
	        while ((line = reader.readLine()) != null) {
	        	response = line;
	        }
	        reader.close();
	        connection.disconnect();
	        logger.debug("#########  查询接口调用成功, 返回报文为: \n{}", response);
		} catch (Exception e) {
			e.printStackTrace();
			logger.debug("#########  查询接口调用失败!  #########");
		}
		return response;
	}
}